#include <elf.h>
#include <filesystem.h>
#include <printThings.h>
#include <multitasking.h>

/*load elf*/

struct ElfHeader *elfh;
struct ElfProgramHeader *progh;

void loadElfBinary(char* path) {
    unsigned int endAddr = 0;

    printf("reading: %s\n", path);
    MyFile f = decodePathToFile(path);
    if (f.size == -1) {
        printf("Konnte Datei nicht Finden\n");
        return;
    }
    printf("leseDatei\n");

    MyFile erg = readFile(f.sektor, f.size);

    const char *file = (const char *)erg.addr;
    int i;

    printf("size: %y\n", f.size);

    elfh = (struct ElfHeader *)file;

    //printf("Binary Information\n");
    //printf("Elf Identifikation: ");
    //printf("%c", elfh->ident[1]);
    //printf("%c", elfh->ident[2]);
    //printf("%c\n", elfh->ident[3]);

    //printf("ELF type %d: ", elfh->type);
    /*
     switch(elfh->type){
        case ET_NONE:{
           printf("kein Typ\n");
           break;
        }
        case ET_REL:{
           printf("Relocatable Datei\n");
           break;
        }
        case ET_EXEC:{
           printf("Ausfuehrbare Datei\n");
           break;
        }
        case ET_DYN:{
           printf("Shared-Object-Datei\n");
           break;
        }
     }

     printf("Entrypoint: %y\n", elfh->entry);
     printf("Offset des ProgrammHeaders: %y\n", elfh->programHeaderOffset);
     printf("Groesse eines ProgrammHeader eintrags: %y\n", elfh->sizeOfProgrammHeaderEntry);
     printf("Anzahl von ProgrammHeader eintraegen %d\n\n", elfh->countProgrammHeaderEntrys);
    */

    struct kernelPagingStructure vA = makePageDirForTask();

    for (i = 0; i < elfh->countProgrammHeaderEntrys; i++) {
        printf("ProgramHeader %d\n", (i + 1));
        progh = (struct ElfProgramHeader *)((file + elfh->programHeaderOffset) + (i * elfh->sizeOfProgrammHeaderEntry));

        if (progh->type != PT_LOAD)
            continue;
        
        //printf("Segmenttyp: %x\n", progh->type);
        //printf("Dateioffset, an dem das Segment steht: %x\n", progh->fileOffset);
        //printf("Virtuelle Adresse: %x\n", progh->vAddr);
        //printf("Groesse des Segments (Datei): %x\n", progh->fileSegmentSize);
        //printf("Groesse des Segments (Memory): %x\n", progh->fileMemorySize);
        //printf("Alignment: %x\n", progh->alignment);
        
        endAddr = copyProgramToVAddrRoom(file + progh->fileOffset, progh->fileMemorySize, progh->vAddr);
        
    }

    addTaskCount();
    initTask(elfh->entry, vA, endAddr);

    //initTask(elfh->entry, vA, endAddr);
}

